import re
import prettytable as pt

string = '##0865ST=32;CN=2051;PW=123456;MN=88888881234567;Flag=0;CP=&&DataTime=20200106134400;T10-Min=21386.000,T10-Avg=21498.502,T10-Max=21611.000,T10-Cou=21498.502;T11-Min=21384.000,T11-Avg=21496.502,T11-Max=21609.000,T11-Cou=21496.502;T12-Min=21384.000,T12-Avg=21496.502,T12-Max=21609.000,T12-Cou=21496.502;T20-Min=21383.000,T20-Avg=21495.502,T20-Max=21608.000,T20-Cou=21495.502;T21-Min=21382.000,T21-Avg=21494.502,T21-Max=21607.000,T21-Cou=21494.502;T22-Min=21382.000,T22-Avg=21494.502,T22-Max=21607.000,T22-Cou=21494.502;T30-Min=21382.000,T30-Avg=21494.502,T30-Max=21607.000,T30-Cou=21494.502;901-Min=21381.000,901-Avg=21493.502,901-Max=21606.000,901-Cou=21493.502;01-Min=21380.000,01-Avg=21492.502,01-Max=21605.000,01-Cou=55423.574;02-Min=21379.000,02-Avg=21491.502,02-Max=21604.000,02-Cou=55420.996;B02-Min=21377.000,B02-Avg=21489.502,B02-Max=21602.000,B02-Cou=2578740.250&&D201\r\n'
# string = '##0191ST=32;CN=2011;PW=123456;MN=88888881234567;Flag=0;CP=&&DataTime=20200106131830;901-Rtd=0.0000,901-Flag=T01-Rtd=18664.0000,01-Flag=T;02-Rtd=18663.0000,02-Flag=T;B02-Rtd=18661.0000,B02-Flag=T&&D1C1\r\n'
'''
##0191ST=32;CN=2011;PW=123456;MN=88888881234567;Flag=0;CP=&&
DataTime=20200106131830;
901-Rtd=0.0000,901-Flag=T;
01-Rtd=18664.0000,01-Flag=T;
02-Rtd=18663.0000,02-Flag=T;
B02-Rtd=18661.0000,B02-Flag=T
&&D1C1\r\n
'''

'''
"data-len" : 191		# 固定字段
"data" : {				# 固定字段
    "ST" : "32"			# 活动字段
    "CN" : "2011"		# 活动字段
    ......
    "CP" : {			# 固定字段
        "DataTime" : "20200106131830"	# 活动字段
        "901" : {						# 活动字段
            "Rtd" : 0.0000				# 活动字段
            "Flag" : "T"				# 活动字段
        }
        "01" : {
            "Rtd" : 0.0000
            "Flag" : "T"
        }
        ......
    }
}
"crc" : "D1C1"			# 固定字段
'''

def get_kv(string, key, split="=", default="null"):
    r = re.search('%s[^,;&]*'%(key), string)
    if r == None:
        result = default        
        return result
    s = r.group().split(split)
    if len(s) < 2:
        result = default
    else:
        result = s[1]
    return result

# pattern_hj212_kv = re.compile('[^;]*;')
def hj212_msg_check(string):
    pass
def hj212_parse(string):
    result = {}
    # 校验包
    if not "##" in string:
        return result
    if not "\r\n" in string:
        return result
    string = string[string.index("##"):]
    # 保留原始数据
    result["raw-data"] = string
    # print("{", result["raw-data"], "}")
    # print("{", str(result["raw-data"]), "}")
    # 提取data-len
    result["data-len"] = int(string[2 : 6])
    # 提取CRC
    index = string.index("\r")
    result["crc"] = string[index - 4 : index]
    # 提取data
    string = string[6 : index - 4]
    result["data"] = {}
    result["data"]["CP"] = {}

    # 提取解析CP字段
    try:
        cp_string = string[string.index("CP=&&") + 5 : -2]
        if len(cp_string) > 0:
            cp = cp_string.split(";")       # 分割字段
            for kvs in cp:
                kvs = kvs.split(",")        # 分割字段
                for kv in kvs:
                    if "-" in kv:           # 区分01-Rtd和DataTime
                        kv = kv.split("=")
                        sl = kv[0].split("-")
                        sl.append(kv[1])
                        # print(len(sl), sl)
                        if not sl[0] in result["data"]["CP"]:
                            result["data"]["CP"][sl[0]] = {}
                        result["data"]["CP"][sl[0]][sl[1]] = sl[2]
                    else:
                        sl = kv.split("=")
                        if len(sl) != 2:
                            continue
                        result["data"]["CP"][sl[0]] = sl[1]
            # print (kv)
    except Exception as e:
        pass
        # result["data"]["CP"] = cp_string
    # 解析数据段
    # kvs = pattern_hj212_kv.findall(string[:string.index("CP=&&")])
    kvs = string[:string.index("CP=&&")].split(";")
    if kvs:
        for kv in kvs:
            s = kv.split("=")
            if len(s) != 2:
                continue
            result["data"][s[0]] = s[1]
    return result

class hj212_msg:
    def __init__(self, string, default=None, **argv):
        self.msg = hj212_parse(string)
        for key in argv:
            self.msg[key] = argv[key]
        self.default = default
    def item_key(self, *keys):
        result = self.default
        msg = self.msg
        for key in keys:
            if not isinstance(msg, dict):
                break
            if key in msg:
                msg = msg[key]
            else:
                break
        else:
            result = msg
        return result
    def item(self, path):
        path = path.split("/")
        return self.item_key(*path)
    def table(self):
        if not isinstance(self.item("data/CP"), dict):    # 检查是否存在CP字段
            return
        table_len = 1                                   # 初始1
        for field in self.item("data/CP"):            # 计算最大表项
            value = self.item("data/CP/%s"%(field))
            if not isinstance(value, dict):
                continue
            tmp = len(value)
            if tmp > table_len:
                table_len = tmp
        table_len += 1
        tb = pt.PrettyTable()   
        tb.field_names = ["Item%d"%(i) for i in range(0, table_len)]    # 创建表项
        # 设置表格 - begin
        for item in tb.field_names:
            tb.align[item] = 'l'
        # tb.set_style(pt.DEFAULT)
        # tb.set_style(pt.MSWORD_FRIENDLY)
        tb.set_style(pt.PLAIN_COLUMNS)
        # tb.set_style(pt.RANDOM)
        # 设置表格 - end
        null_list = ["" for i in range(0, table_len)]
        tab_id = 0
        for field in self.item("data"):               # 添加非CP的字段
            if field is "CP":
                continue
            tmp = list(null_list)
            tmp[1] = "%s=%s"%(field,str(self.item("data/%s"%(field))))
            tmp[0] = str(tab_id)
            tab_id += 1
            tb.add_row(tmp)
        for field in self.item("data/CP"):            # 添加CP字段
            tmp = list(null_list)
            if isinstance(self.item("data/CP/%s"%(field)), dict): # 需要一列展示的
                index = 1
                for subfield in self.item("data/CP/%s"%(field)):
                    tmp[index] = "%s-%s=%s"%(field, subfield, str(self.item("data/CP/%s/%s"%(field, subfield))))
                    index += 1
            else:                                       # 不需要一列展示的
                tmp[1] = "%s=%s"%(field,str(self.item("data/CP/%s"%(field))))
            tmp[0] = str(tab_id)
            tab_id += 1
            tb.add_row(tmp)
        return str(tb)

if __name__ == "__main__":
    print(string)
    # print(hj212_parse(string))
    msg = hj212_msg(string)
    print(msg.msg)
    print()
    print(len(msg.msg["data"]["CP"]["T10"]), msg.msg["data"]["CP"]["T10"])
    print(msg.table())
    '''
    print(msg.item_key("data", "ST"))
    print(msg.item_key("raw-data"))
    print(msg.item_key("raw-data", "123"))
    print(msg.item_key("data", "CP", "901", "Rtd"))
    print(msg.item_key("data", "CP", "901", "Flag"))
    print(msg.item_key("data", "CP", "901"))

    print(msg.item("data/ST"))
    print(msg.item("raw-data"))
    print(msg.item("raw-data/123"))
    print(msg.item("data/CP/901/Rtd"))
    print(msg.item("data/CP/901/Flag"))
    print(msg.item("data/CP/901"))
    print(msg.item("data/CP/901/"))
    print(msg.item("/data/CP/901/"))
    '''
